package com.mj.flowable.examples.controller;


import com.mj.flowable.examples.vo.TaskExt;
import org.apache.commons.beanutils.BeanUtils;
import org.flowable.bpmn.model.*;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;

@Controller
public class PageController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ProcessEngine processEngine;



    @RequestMapping("/index")
    public String index()
    {
        return "index";
    }


    @RequestMapping("/processDefineList")
    public String processList(HttpServletRequest request)
    {
        List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().orderByProcessDefinitionVersion().asc().list();
        request.setAttribute("processDefinitions",processDefinitions);
        return "processDefineList";
    }


    @RequestMapping("/taskListPage")
    public String taskListPage(HttpServletRequest request) throws InvocationTargetException, IllegalAccessException {
        TaskService taskService = processEngine.getTaskService();
        List<TaskEntityImpl> tasks = (List)taskService.createTaskQuery().active().orderByTaskCreateTime().desc().list();
        List<TaskExt> taskExts = new LinkedList<>();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        for(TaskEntityImpl task:tasks)
        {
            TaskExt taskExt = new TaskExt();
            taskExt.setId(task.getId());
            taskExt.setName(task.getName());
            taskExt.setExecutionId(task.getExecutionId());
            taskExt.setAssignee(task.getAssignee());
            taskExt.setOwner(task.getOwner());
            taskExt.setProcessInstanceId(task.getProcessInstanceId());
            taskExt.setProcessDefinitionId(task.getProcessDefinitionId());
            taskExt.setVariableCount(task.getVariableCount());
            taskExt.setCreateTime(task.getCreateTime());
            taskExt.setCreateDateString(dateFormat.format(taskExt.getCreateTime()));
            taskExt.setTaskDefinitionKey(task.getTaskDefinitionKey());

            if(task.getExecutionId()!=null) {
                ExecutionEntity executionEntity = (ExecutionEntity) processEngine.getRuntimeService().createExecutionQuery()
                        .executionId(task.getExecutionId()).singleResult();
                String crruentActivityId = executionEntity.getActivityId();
                BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
                FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(crruentActivityId);
                // 输出连线
                List<SequenceFlow> outFlows = flowNode.getOutgoingFlows();
                for (SequenceFlow sequenceFlow : outFlows) {
                    //当前审批节点
                    FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
                    taskExt.setCurrentNodeCode(sourceFlowElement.getId());
                    taskExt.setCurrentNodeName(sourceFlowElement.getName());

                    // 下一个审批节点
                    FlowElement targetFlow = sequenceFlow.getTargetFlowElement();
                    if (targetFlow instanceof UserTask) {
                        taskExt.setNextNodeCode(targetFlow.getId());
                        taskExt.setNextNodeName(targetFlow.getName());
                    }
                    if (targetFlow instanceof ExclusiveGateway) {
                        taskExt.setNextNodeCode(targetFlow.getId());
                        taskExt.setNextNodeName("网关");
                    }
                    // 如果下个审批节点为结束节点
                    if (targetFlow instanceof EndEvent) {
                        taskExt.setNextNodeCode(targetFlow.getId());
                        taskExt.setNextNodeName("结束:" + targetFlow.getName());
                    }

                }
            }
            taskExts.add(taskExt);
        }
        request.setAttribute("tasks",taskExts);
        return "taskList";
    }




    @RequestMapping("/startTaskPage")
    public String startTaskPage(HttpServletRequest request, @RequestParam String processDefineKey) throws InvocationTargetException, IllegalAccessException {
        request.setAttribute("processDefineKey",processDefineKey);
        return "startTask";
    }



    @RequestMapping("/assigneePage")
    public String assigneePage(HttpServletRequest request, @RequestParam String taskId) throws InvocationTargetException, IllegalAccessException {
        request.setAttribute("taskId",taskId);
        return "assigneePage";
    }

    @RequestMapping("/transferPage")
    public String transferPage(HttpServletRequest request, @RequestParam String taskId,@RequestParam String oldAssignee) throws InvocationTargetException, IllegalAccessException {
        request.setAttribute("taskId",taskId);
        request.setAttribute("oldAssignee",oldAssignee);
        return "transferPage";
    }




    @RequestMapping("/flowChatPage")
    public String flowChatPage(HttpServletRequest request, @RequestParam String processInstanceId) throws InvocationTargetException, IllegalAccessException {
        request.setAttribute("processInstanceId",processInstanceId);
        return "flowChat";
    }

}
